package com.time.oss.adpater;

import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.time.oss.entity.FileInfo;
import com.qiniu.storage.model.FileListing;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 七牛云存储适配器
 */
@Component
@RefreshScope
public class QiniuStorageAdapter implements StorageAdapter {

    @Resource
    private UploadManager uploadManager;

    @Resource
    private BucketManager bucketManager;

    @Resource
    private Auth auth;

    @Value("${qiniu.domain}")
    private String domain;

    @Value("${qiniu.region:auto}")
    private String region;

    @Value("${qiniu.usePrivate:false}")
    private boolean usePrivate;

    @Value("${qiniu.downloadExpireSeconds:3600}")
    private long downloadExpireSeconds;

    @Override
    public void createBucket(String bucketName) {
        try {
            bucketManager.createBucket(bucketName, region);
        } catch (QiniuException e) {
            if (e.code() != 614) {
                throw new RuntimeException("创建七牛 Bucket 失败: " + e.response.toString(), e);
            }
        }
    }

    @Override
    public void uploadFile(MultipartFile uploadFile, String bucketName, String objectName) {
        try {
            createBucket(bucketName);
            String key = buildObjectKey(uploadFile, objectName);
            Response response = uploadManager.put(uploadFile.getInputStream(), key, auth.uploadToken(bucketName), null, null);
            if (!response.isOK()) {
                throw new RuntimeException("上传七牛文件失败: " + response.bodyString());
            }
        } catch (IOException e) {
            throw new RuntimeException("上传七牛文件流失败", e);
        }
    }

    @Override
    public List<String> getAllBucket() {
        try {
            String[] buckets = bucketManager.buckets();
            return buckets == null ? List.of() : Arrays.asList(buckets);
        } catch (QiniuException e) {
            throw new RuntimeException("获取七牛 Bucket 失败", e);
        }
    }

    @Override
    public List<FileInfo> getAllFile(String bucketName) {
        try {
            List<FileInfo> files = new ArrayList<>();
            String marker = null;
            do {
                FileListing listing = bucketManager.listFiles(bucketName, "", marker, 1000, null);
                if (listing == null || listing.items == null) {
                    break;
                }
                for (com.qiniu.storage.model.FileInfo item : listing.items) {
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setFileName(item.key);
                    fileInfo.setDirectoryFlag(false);
                    fileInfo.setEtag(item.hash);
                    files.add(fileInfo);
                }
                marker = listing.marker;
                if (listing.isEOF()) {
                    break;
                }
            } while (true);
            return files;
        } catch (QiniuException e) {
            throw new RuntimeException("查询七牛文件列表失败", e);
        }
    }

    @Override
    public InputStream downloadFile(String bucketName, String objectName) {
        try {
            URL url = new URL(getUrl(bucketName, objectName));
            URLConnection conn = url.openConnection();
            return conn.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException("下载七牛文件失败", e);
        }
    }

    @Override
    public void deleteBucket(String bucketName) {
        throw new UnsupportedOperationException("七牛云暂不支持通过 SDK 删除空间，请前往控制台操作");
    }

    @Override
    public void deleteBucket(String bucketName, String objectName) {
        try {
            bucketManager.delete(bucketName, objectName);
        } catch (QiniuException e) {
            throw new RuntimeException("删除七牛文件失败", e);
        }
    }

    @Override
    public String getUrl(String bucketName, String objectName) {
        String normalizedDomain = domain.endsWith("/") ? domain.substring(0, domain.length() - 1) : domain;
        String normalizedObject = objectName.startsWith("/") ? objectName.substring(1) : objectName;
        String baseUrl = normalizedDomain + "/" + normalizedObject;
        if (usePrivate) {
            return auth.privateDownloadUrl(baseUrl, downloadExpireSeconds);
        }
        return baseUrl;
    }

    private String buildObjectKey(MultipartFile uploadFile, String objectName) {
        String filename = uploadFile.getOriginalFilename();
        if (!StringUtils.hasText(filename)) {
            filename = uploadFile.getName();
        }
        if (!StringUtils.hasText(objectName)) {
            return filename;
        }
        return objectName.endsWith("/") ? objectName + filename : objectName + "/" + filename;
    }
}

